package com.siyoumi.app.modules.mall2.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.siyoumi.app.entity.M2Order;
import com.siyoumi.app.entity.M2OrderItem;
import com.siyoumi.app.entity.M2OrderRefund;
import com.siyoumi.app.entity.SysOrder;
import com.siyoumi.app.modules.mall2.entity.RefundAuditStatus;
import com.siyoumi.app.modules.mall2.vo.*;
import com.siyoumi.app.sys.service.IPayOrder;
import com.siyoumi.app.sys.service.payorder.PayOrder;
import com.siyoumi.app.service.*;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.exception.XException;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.*;
import com.siyoumi.component.XApp;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SvcM2Order
        implements IWebService {
    static public SvcM2Order getBean() {
        return XSpringContext.getBean(SvcM2Order.class);
    }

    static public M2OrderService getApp() {
        return M2OrderService.getBean();
    }

    /**
     * 下单
     *
     * @param vo
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn order(OrderVo vo) {
        List<String> skuIds = vo.getList().stream().map(OrderItemVo::getSku_id).collect(Collectors.toList());
        List<SkuData> listSku = SvcM2Sku.getBean().getList(null, skuIds);
        if (skuIds.size() != listSku.size()) {
            return XReturn.getR(20046, "sku_id存在异常，请刷新页面");
        }

        List<OrderItemVo> listOrderItemVo = new ArrayList<>();
        log.debug("验证sku");
        for (OrderItemVo orderItemVo : vo.getList()) {
            //获取对应的sku
            log.debug("验证：{}", orderItemVo.getSku_id());
            SkuData skuData = listSku.stream().filter(item -> item.getEntity().getMsku_id().equals(orderItemVo.getSku_id()))
                    .findFirst().get();
            orderItemVo.setSkuData(skuData);

            String skuFullName = skuData.getMspu_name() + skuData.getEntity().getMsku_name();
            log.debug("有效检查");
            XReturn r = SvcM2Sku.getBean().valid(skuData);
            if (r.err()) {
                r.setErrMsg(skuFullName, ":", r.getErrMsg());
                return r;
            }

            log.debug("库存，限购检查");
            r = SvcM2Sku.getBean().validLimit(skuData, getOpenid(), orderItemVo.getCount());
            if (r.err()) {
                r.setErrMsg(skuFullName, ":", r.getErrMsg());
                return r;
            }

            listOrderItemVo.add(orderItemVo);
        }

        log.debug("扣库存");
        for (OrderItemVo orderItemVo : vo.getList()) {
            SysStockService.getBean().subStock(orderItemVo.getSku_id(), orderItemVo.getCount().longValue());
        }

        //新建主订单
        M2Order entityOrder = newOrder(vo, listOrderItemVo);

        log.debug("清购物车");
        List<String> mcatIds = vo.getList().stream()
                .filter(item -> XStr.hasAnyText(item.getCart_id()))
                .map(OrderItemVo::getCart_id)
                .collect(Collectors.toList());
        if (mcatIds.size() > 0) {
            SvcM2Cart.getBean().delete(mcatIds);
        }


        XReturn r = XReturn.getR(0);
        r.setData("entity_order", entityOrder);
        return r;
    }

    /**
     * 支付
     *
     * @param orderId
     */
    public XReturn orderPay(String orderId) {
        SysOrder entityPayOrder = SysOrderService.getBean().getEntityByOrderId(orderId);
        IPayOrder app = PayOrder.getIns(entityPayOrder);
        return app.pay(null);
    }

    /**
     * 订单列表
     *
     * @param inputData
     */
    public JoinWrapperPlus<M2Order> orderQuery(InputData inputData) {
        String orderId = inputData.input("order_id");
        String itemId = inputData.input("item_id");
        String openid = inputData.input("openid");
        String spuName = inputData.input("spu_name");
        String address_name = inputData.input("address_name");
        String address_phone = inputData.input("address_phone");
        String payStatus = inputData.input("pay_status");
        String create_date_begin = inputData.input("create_date_begin");
        String create_date_end = inputData.input("create_date_end");
        String morder_deliver = inputData.input("morder_deliver");
        String refundAuditStatus = inputData.input("refund_audit_status");
        String status = inputData.input("status");
        //query
        M2OrderService app = SvcM2Order.getApp();
        JoinWrapperPlus<M2Order> query = app.join();
        query.join(SysOrder.table(), "morder_id", "order_order_id"); //支付订单
        query.select("t_m2_order.*"
                , "order_expire_date", "order_expire_handle", "order_pay_ok", "order_pay_ok_date"
        );
        query.eq("morder_openid", getOpenid())
                //.eq("main_cancel", 0) //未取消
                //.eq("morder_enable", 1) //有效订单
                .orderByDesc("morder_create_date")
                .orderByAsc("morder_id")
        ;
        if (XStr.hasAnyText(orderId)) { //订单号
            query.eq("morder_id", orderId);
        } else if (XStr.hasAnyText(itemId)) { //子订单号
            query.eq("moitem_id", itemId);
        } else {
            if (XStr.hasAnyText(openid)) { //openid
                query.eq("wxuser_id", openid);
            }
            if (XStr.hasAnyText(address_name)) { //姓名
                query.likeRight("morder_address_name", address_name);
            }
            if (XStr.hasAnyText(spuName)) { //商品名称
                query.like("moitem_spu_name", spuName);
            }
            if (XStr.hasAnyText(address_phone)) { //手机号
                query.likeRight("morder_address_phone", address_phone);
            }
            if (XStr.hasAnyText(payStatus)) { //支付状态
                switch (NumberUtils.toInt(payStatus, 0)) {
                    case 0:
                        query.eq("payorder_pay_ok", 0);
                        break;
                    case 1:
                        query.eq("payorder_pay_ok", 1);
                        break;
                }
            }
            if (XStr.hasAnyText(create_date_begin)
                    && XStr.hasAnyText(create_date_end)) { //创建订单时间
                LocalDateTime b = XStr.toDateTime(create_date_begin);
                LocalDateTime e = XStr.toDateTime(create_date_end);
                query.between("payorder_create_date", b, e);
            }
            if (XStr.hasAnyText(morder_deliver)) { //发货状态
                if (morder_deliver.equals("2")) {
                    query.eq("morder_done", 1);
                } else {
                    query.eq("morder_deliver", morder_deliver);
                }
            }
            if (XStr.hasAnyText(refundAuditStatus)) { //退款审核状态
                query.eq("mref_audit_status", refundAuditStatus);
            }
        }
        if (XStr.hasAnyText(status)) { //订单状态
            switch (status) {
                case "0": //待付款
                    query.eq("morder_enable", 1);
                    query.eq("morder_pay", 0);
                    break;
                case "1": //待发货
                    query.eq("morder_pay", 1);
                    query.eq("morder_deliver", 0);
                    break;
                case "2": //已发货
                    query.eq("morder_pay", 1);
                    query.eq("morder_deliver", 1);
                    query.eq("morder_done", 0);
                    break;
                case "3": //已完成
                    query.eq("morder_pay", 1);
                    query.eq("morder_done", 1);
                    break;
            }
        }

        return query;
    }

    /**
     * 检查支付
     *
     * @param orderId
     */
    public XReturn orderPayCheck(String orderId) {
        SysOrder entityPayOrder = SysOrderService.getBean().getEntityByOrderId(orderId);
        IPayOrder app = PayOrder.getIns(entityPayOrder);
        return app.payCheck();
    }

    /**
     * 取消支付
     *
     * @param orderId
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn orderCancel(String orderId) {
        SysOrder entityPayOrder = SysOrderService.getBean().getEntityByOrderId(orderId);
        if (!entityPayOrder.getOrder_uid().equals(getOpenid())) {
            return XReturn.getR(20002, "非本人");
        }

        IPayOrder app = PayOrder.getIns(entityPayOrder);
        return app.cancel();
    }

    /**
     * 订单已完成
     *
     * @param vo     0：用户操作；1：后台管理员操作；2：任务操作；
     */
    public XReturn orderDone(VoOrderDone vo) {
        M2Order entityM2Order = SvcM2Order.getApp().getEntity(vo.getOrder_id());
        if (entityM2Order == null) {
            return EnumSys.ERR_VAL.getR("订单ID异常");
        }
        if (vo.getSrc() == 0) {
            if (!entityM2Order.getMorder_openid().equals(getOpenid())) {
                return EnumSys.ERR_OPENID.getR("非本人");
            }
        }
        if (entityM2Order.getMorder_done() == 1) {
            return XReturn.getR(20217, "订单已完成");
        }

        log.debug("锁总单");
        SysOrder entitySysOrder = SysOrderService.getBean().getEntityByOrderId(entityM2Order.getMorder_id(), true);
        if (!entitySysOrder.checkPayOk()) {
            return XReturn.getR(20223, "订单未付款");
        }

        M2Order entityUpdate = new M2Order();
        entityUpdate.setMorder_id(entityM2Order.getMorder_id());
        entityUpdate.setMorder_done(1);
        entityUpdate.setMorder_deliver(entityM2Order.getMorder_deliver());
        entityUpdate.setMorder_done_date(LocalDateTime.now());
        M2OrderService.getBean().updateById(entityUpdate);

        return XReturn.getR(0);
    }

    /**
     * 订单发货
     */
    public XReturn orderDeliver(OrderDeliverVo vo) {
        M2Order entityM2Order = SvcM2Order.getApp().getEntity(vo.getOrder_id());
        if (entityM2Order == null) {
            return EnumSys.ERR_VAL.getR("订单ID异常");
        }
        //可修改
        //if (entityOrder.isDeliver()) {
        //    return CommonReturn.funcNew(20217, "订单已发货");
        //}
        XLog.debug(this.getClass(), "锁总单");
        SysOrder entitySysOrder = SysOrderService.getBean().getEntityByOrderId(entityM2Order.getMorder_id(), true);
        if (!entitySysOrder.checkPayOk()) {
            return XReturn.getR(20223, "订单未付款");
        }

        M2Order entityUpdate = new M2Order();
        entityUpdate.setMorder_id(entityM2Order.getMorder_id());
        entityUpdate.setMorder_deliver(1);
        entityUpdate.setMorder_deliver_no(vo.getDeliver_no());
        entityUpdate.setMorder_deliver_store(vo.getDeliver_store());
        entityUpdate.setMorder_deliver_date(LocalDateTime.now());
        M2OrderService.getBean().updateById(entityUpdate);

        return XReturn.getR(0);
    }

    /**
     * 修改地址
     *
     * @param orderIds
     * @param vo
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn orderAddressEdit(List<String> orderIds, OrderAddressVo vo) {
        for (String orderId : orderIds) {
            M2Order entityM2Order = SvcM2Order.getApp().getEntity(orderId);
            if (!entityM2Order.getMorder_openid().equals(getOpenid())) {
                throw new XException(EnumSys.ERR_OPENID.getR("非本人操作"));
            }
            if (entityM2Order.getMorder_deliver() == 1) {
                throw new XException(XReturn.getR(20243, "订单已发货"));
            }

            M2Order entityUpdate = new M2Order();
            entityUpdate.setMorder_id(entityM2Order.getMorder_id());
            entityUpdate.setMorder_addr_address(vo.getAddress());
            entityUpdate.setMorder_addr_user_name(vo.getUser_name());
            entityUpdate.setMorder_addr_user_phone(vo.getUser_phone());
            SvcM2Order.getApp().updateById(entityUpdate);
        }

        return XReturn.getR(0);
    }

    /**
     * 子订单退款详情
     */
    public XReturn orderItemRefundInfo(String itemId) {
        M2OrderItem entityItem = M2OrderItemService.getBean().getEntity(itemId);
        XLog.debug(this.getClass(), "子订单x");
        M2OrderItemService appItemX = M2OrderItemService.getBean();
        JoinWrapperPlus<M2OrderItem> query = appItemX.listQuery(entityItem.getMoitem_id(), null);
        List<M2OrderItem> listx = appItemX.get(query);

        XLog.debug(this.getClass(), "退款订单");
        M2OrderRefund entityRefund = M2OrderRefundService.getBean().getEntityByItemId(entityItem.getKey());

        XReturn r = XReturn.getR(0);
        r.setData("entity_item", entityItem);
        r.setData("entity_refund", entityRefund);
        if (entityRefund != null) {
            r.setData("audit_status", IEnum.toMap(RefundAuditStatus.class));
        }
        r.setData("listx", listx);
        return r;
    }

    /**
     * 子订单申请退款
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn orderItemRefund(OrderItemRefundVo vo) {
        M2OrderItem entityItem = M2OrderItemService.getBean().getEntity(vo.getItem_id());

        M2OrderRefund entityRefund = M2OrderRefundService.getBean().getEntityByItemId(vo.getItem_id());
        if (entityRefund != null) {
            return XReturn.getR(20300, "订单已申请过退款");
        }

        XLog.debug(this.getClass(), "锁支付单");
        SysOrder entitySysOrder = SysOrderService.getBean().getEntityByOrderId(entityItem.getMoitem_morder_id(), true);
        if (!entitySysOrder.checkPayOk()) {
            return XReturn.getR(20310, "订单未支付");
        }

        XLog.debug(this.getClass(), "创建总订单");
        entityRefund = new M2OrderRefund();
        entityRefund.setMref_x_id(entityItem.getMoitem_x_id());
        entityRefund.setMref_order_id(entityItem.getMoitem_morder_id());
        entityRefund.setMref_item_id(entityItem.getMoitem_id());
        entityRefund.setMref_openid(entityItem.getMoitem_openid());
        //退款金额
        double refundPrice = entityItem.getMoitem_sku_price().doubleValue() * entityItem.getMoitem_count();
        entityRefund.setMref_apply_price(BigDecimal.valueOf(refundPrice));
        entityRefund.setMref_refund_desc(vo.getDesc());
        //退款订单号
        entityRefund.setMref_refund_id(entityItem.getMoitem_id());
        entityRefund.setAutoID();
        M2OrderRefundService.getBean().save(entityRefund);

        XReturn r = XReturn.getR(0);
        r.setData("entity_refund", entityRefund);
        return r;
    }

    /**
     * 退款订单审核
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn orderItemRefundAudit(OrderItemRefundAuditVo vo) {
        if (vo.getAudit_status().equals(-20)) {
            //撤回pass
        } else {
            if (XStr.isNullOrEmpty(vo.getAudit_acc())) {
                return XReturn.getR(20350, "缺少审核人ID");
            }
        }

        M2OrderRefund entityRefund = M2OrderRefundService.getBean().getEntityLock(vo.getRefund_id());
        if (entityRefund == null) {
            return XReturn.getR(20360, "退款订单ID异常");
        }

        XLog.debug(this.getClass(), "锁支付订单");
        SysOrder entitySysOrder = SysOrderService.getBean().getEntityByOrderId(entityRefund.getMref_order_id(), true);

        if (entityRefund.getMref_audit_status() != 0) {
            return XReturn.getR(20361, "退款订单已审核");
        }

        XLog.debug(this.getClass(), "更新退款订单状态");
        M2OrderRefund entityRefundUpdate = new M2OrderRefund();
        entityRefundUpdate.setMref_id(entityRefund.getMref_id());
        entityRefundUpdate.setMref_audit_status(vo.getAudit_status());
        entityRefundUpdate.setMref_audit_date(LocalDateTime.now());
        entityRefundUpdate.setMref_audit_acc(vo.getAudit_acc());
        if (vo.auditOk()) {
            XLog.debug(this.getClass(), "审核通过，设置退款数量和金额");
            if (vo.getRefund_price() == null) {
                return XReturn.getR(20362, "缺少退款金额");
            }
            if (vo.getRefund_price().doubleValue() <= 0) {
                return XReturn.getR(20365, "退款金额异常：0");
            }

            //可退款最大金额
            M2OrderItem entityOrderItem = M2OrderItemService.getBean().getEntity(entityRefund.getMref_item_id());
            BigDecimal refundPriceMax = entityOrderItem.getMoitem_sku_price().multiply(new BigDecimal(entityOrderItem.getMoitem_count().toString()));
            XLog.debug(this.getClass(), "可退款最大金额:", refundPriceMax);
            if (vo.getRefund_price().compareTo(refundPriceMax) < 0) {
                XReturn r = XReturn.getR(20368, "退款金额超出原订单金额");
                r.setData("refund_price", vo.getRefund_price());
                r.setData("refund_price_max", refundPriceMax);
                return r;
            }
            entityRefundUpdate.setMref_refund_price(vo.getRefund_price());
        } else {
            XLog.debug(this.getClass(), "审核不通过或撤回订单，更新refund_id，防止唯一报错");
            entityRefundUpdate.setMref_refund_id(entityRefund.getMref_refund_id() + XDate.toS());
        }
        if (XStr.hasAnyText(vo.getAudit_desc())) { //描述
            entityRefund.setMref_refund_desc(vo.getAudit_desc());
        }
        M2OrderRefundService.getBean().updateById(entityRefundUpdate);


        if (vo.auditOk()) {
            XLog.debug(this.getClass(), "退款成功，并返还库存");
            M2OrderItem entityItem = M2OrderItemService.getBean().getEntity(entityRefund.getMref_item_id());
            SysStockService.getBean().subStock(entityItem.getMoitem_sku_id(), entityItem.getMoitem_count());
        }

        return XReturn.getR(0);
    }

    /**
     * 根据商家ID获取子订单项
     *
     * @param orderIds
     */
    protected List<M2OrderItem> orderItemList(List<String> orderIds) {
        if (orderIds.size() <= 0) {
            return new ArrayList();
        }
        M2OrderItemService app = M2OrderItemService.getBean();
        QueryWrapper<M2OrderItem> query = app.join();
        query.in("moitem_order_id", orderIds);

        return app.get(query);//sku
    }

    /**
     * 新建订单
     *
     * @param vo         下单提交参数
     * @param listItemvo 参数子项，有sku信息
     * @return
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public M2Order newOrder(OrderVo vo, List<OrderItemVo> listItemvo) {
        XLog.debug(this.getClass(), "新建订单order");
        M2Order entityOrder = new M2Order();
        entityOrder.setMorder_x_id(XHttpContext.getX());
        entityOrder.setMorder_app_id("mall2");
        entityOrder.setMorder_openid(getOpenid());
        entityOrder.setMorder_addr_user_name(vo.getUser_name());
        entityOrder.setMorder_addr_user_phone(vo.getUser_phone());
        entityOrder.setMorder_addr_address(vo.getAddress());
        entityOrder.setMorder_id(XApp.getStrID("O"));

        XLog.debug(this.getClass(), "商家订单总金额");
        double price = listItemvo.stream()
                .mapToDouble(item -> item.getSkuData().getEntity().getMsku_price().doubleValue() * item.getCount()).sum();
        entityOrder.setMorder_price(BigDecimal.valueOf(price));
        entityOrder.setMorder_price_pay(entityOrder.getMorder_price());
        //保存订单
        SvcM2Order.getApp().save(entityOrder);


        StringBuffer orderDesc = new StringBuffer(); //订单描述

        XLog.debug(this.getClass(), "新建子订单");
        List<M2OrderItem> listItem = listItemvo.stream().map(item ->
        {
            M2OrderItem entityItem = new M2OrderItem();
            entityItem.setMoitem_app_id(entityOrder.getMorder_app_id());
            entityItem.setMoitem_x_id(entityOrder.getMorder_x_id());
            entityItem.setMoitem_morder_id(entityOrder.getMorder_id());
            entityItem.setMoitem_openid(entityOrder.getMorder_openid());
            entityItem.setMoitem_sku_id(item.getSku_id());
            entityItem.setMoitem_count(item.getCount().longValue());
            entityItem.setMoitem_spu_name(item.getSkuData().getMspu_name());
            entityItem.setMoitem_spu_pic(item.getSkuData().getMspu_pic());
            entityItem.setMoitem_sku_name(item.getSkuData().getEntity().getMsku_name());
            entityItem.setMoitem_sku_price(item.getSkuData().getEntity().getMsku_price());
            entityItem.setMoitem_id(XApp.getStrID("I"));
            return entityItem;
        }).collect(Collectors.toList());
        //批量插入
        M2OrderItemService.getBean().saveBatch(listItem);
        XLog.debug(this.getClass(), "更新订单状态");
        setEnable(entityOrder, 1);

        //拼接订单描述
        //衣服黄色,10 * 2,衣服蓝色,10 * 1
        String desc = listItem.stream().map(item ->
        {
            return XStr.concat(item.getMoitem_spu_name()
                    , item.getMoitem_sku_name()
                    , " * " + item.getMoitem_count());
        }).collect(Collectors.joining(","));
        orderDesc.append(desc);

        XLog.debug(this.getClass(), "新建支付订单t_c_order_pay_c");
        newPayOrder(entityOrder, XStr.maxLenByte(orderDesc.toString(), 100, "..."));

        return entityOrder;
    }


    /**
     * 设置状态状态，同步商家订单
     *
     * @param entityOrder
     * @param enable
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public Boolean setEnable(M2Order entityOrder, Integer enable) {
        M2Order entityUpdate = new M2Order();
        entityUpdate.setMorder_id(entityOrder.getKey());
        entityUpdate.setMorder_enable(enable);
        boolean update = SvcM2Order.getApp().updateById(entityUpdate);

        XLog.debug(this.getClass(), "更新子订单enable状态");

        return update;
    }

    protected SysOrder newPayOrder(M2Order entityOrder, String desc) {
        SysOrder entity = new SysOrder();
        entity.setOrder_app_id(entityOrder.getMorder_app_id());
        entity.setOrder_x_id(entityOrder.getMorder_x_id());
        entity.setOrder_uid(entityOrder.getMorder_openid());
        entity.setOrder_id(entityOrder.getKey());
        //订单过期时间
        LocalDateTime expireTime = LocalDateTime.now().plusMinutes(30);
        entity.setOrder_pay_expire_date(expireTime);
        //金额
        entity.setOrder_price(entityOrder.getMorder_price());
        entity.setOrder_pay_price(entityOrder.getMorder_price_pay());
        entity.setOrder_desc(desc);
        SysOrderService.getBean().save(entity);

        return entity;
    }

    /**
     * 用户已购买sku数量
     *
     * @param wxFrom
     * @param skuId
     */
    public Long getSkuCount(String wxFrom, String skuId) {
        M2OrderItemService appOrderItem = M2OrderItemService.getBean();
        //query
        JoinWrapperPlus<M2OrderItem> query = appOrderItem.join();
        query.join(M2Order.table(), "moitem_morder_id", "morder_id");
        //
        query.eq("moitem_openid", wxFrom)
                .eq("morder_enable", 1); //生效状态
        if (XStr.hasAnyText(skuId)) { //sku_id
            query.eq("moitem_sku_id", skuId);
        }
        return appOrderItem.count(query);
    }
}
